<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>11 数组ES5新方法</title>
    <style>
        h1 {
            text-align: center;
        }
    </style>
</head>

<body>
    <h1>11 数组ES5新方法</h1>
    <ul id="list"></ul>
</body>
<script>
    /* 
        方法（常用）： 数组.方法名();
            * push()：往数组尾部添加一个或多个元素，返回数组新的长度 (重要)
            * pop()：删除数组最后一个元素，返回删除的元素 (重要)
            * unshift()：往数开头部添加一个或多个元素，返回数组新的长度
            * shift()：删除数组第一个元素，返回删除的元素
            * aplice(start, dalateNum,...,items)：在数组中插入、删除、替换的通用方法
                * start：起始索引位置
                * dalateNum：要删除的数量
                * items：插入的元素（可以的多个）
            * splice(start,end,[参数3，参数4])：返回数组的片段或子数组，从start开始到end（不包括end所对应的元素），参数3起为可选参数 (重要)
                * 如省略end参数，则截取到数组最后一项，支持负数
            
            * sort()：将数组中的元素排序，并返回排序后的数组 (重要)
                * 默认：以字符串的排列方式（转换成ASSCLL码来比对）
                * 参数（比较函数）：利用fn的返回值来确定数组中两个数的位置（假设两个数为a,b）
                    * 返回负数：确定a在b前 [a,b,...]
                    * 返回0：不改变现有位置
                    * 返回正数：确定a在b后 [b,a,...]
            * reverse()：将数组中的元素颠倒顺序，返回逆序后的数组
            * join(separator)：返回字符串值，其中包含了连接在一起的数组的所有元素 (重要)
                * separator：为分隔符，默认为逗号
            * concat()：连接两个或更多的数组，并返回结果
        
        ES5新方法：不兼容低版本IE浏览器：IE 6 7 8
            * 静态方法： Array.isArray()：判断对象是否为数组 返回true false  构造函数名.方法名()
            * 索引方法： indexOf(): 搜索数组中的元素，并返回它所在的位置.  方法返回keyword在数组中的索引值，如果数组不存在keyword，则返回-1  存在: >= 0 或 != -1
            * 遍历方法：
                * forEach(fn): 遍历方法，与for循环没有太大差别，比for循环方便
                * map(fn): 返回一个数量相等的数组，内容是什么取决于在fn中的返回值
                * filter(fn): 得到执行fn后返回的true时对应的数组元素，利用这个方法课对数组元素进行过滤筛选
                * some(fn): 如果该函数中任何一项返回 true， 则返回true
                * every(fn): 如果该函数对每一项都返回 true， 则返回true
                    参数fn： 函数中有三个形参分别为
                    - item：数组中的每一项；
                    - index：遍历过程中对应的索引值
                    - array：对数组的引用

            * 归并方法（了解）：合并，求和
                * reduce(fn, initVal)
                * reduceRight(fn, initVal)
                    * fn(prev, cur, index, array): fn是每一项调用的函数，函数接受4个参数分别是
                        * prev: 前一次的返回值；
                        * cur: 当前值；
                        * index: 索引值；
                        * array: 当前数组，函数需要返回一个值，这个值会在下一次迭代中作为prev的值
                    * initVal: 迭代初始值（可选），如果缺省，prev的值为数组第一项
            
    */

    var arr1 = [1, 2, 3];
    var arr2 = [4, 5, 6];
    var res = arr1.concat(arr2);
    console.log(res);

    var stu = {
        name: '宋雨琦'
    };
    var num = 88;
    // typeof() : 用于检测基本数据类型； 不能判别复合类型的数据
    console.log(typeof (num)); // number
    console.log(typeof (arr1)); // object
    console.log(typeof (stu)); // object
    console.log(Array.isArray(stu)); // false
    console.log(Array.isArray(arr1)); // true

    // indexOf()
    var arr = [7, 8, 9];
    // 判断数组里面是否含有60
    function has(arr, num) {
        var istrue = true;
        if (arr.indexOf(num) == -1) {
            // 不存在
            istrue = false;
        } else {
            // 存在
            istrue = true;
        }
        return istrue;
    }

    console.log(has(arr, 8));

    // 遍历数组： while/do while/for/for in/forEach():数组的方法，只能给数组使用
    var arr3 = ['cat', 'dog', 'pig', 'rabbit'];
    arr3.forEach(function (item, index, array) { // item：数组里面的值； index：下标； array： 数组本身
        // console.log(item);
        // console.log(index);
        // console.log(array[index]);
        console.log(array);
    });

    // 推荐写法
    arr3.forEach(function (item) { // item：数组里面的值；后面两个参数不常用，一般只写第一个参数item
        console.log(item);
    });

    // map(fn): 返回一个数量相等的数组，内容是什么取决于在fn中的返回值

    // 需求：给数组的每一项增加20%

    var arr4 = [3, 5, 7];

    function map(arr) { // 自己封装的map只能实现每一项增加20%，比较有局限性
        var res = []; // 空数组
        arr.forEach(function (item) {
            res.push((item * 1.2).toFixed(2));
        });
        return res;
    };

    var arr5 = map(arr4);
    console.log('1.2倍后' + arr5);

    // 利用数组map()实现三个不同的需求

    // 需求：给数组的每一项增加20%
    var res1 = arr4.map(function (item) {
        return (item * 1.2).toFixed(2);
    });
    console.log('res1:' + res1);

    // 需求：给数组的每一项加5
    var res2 = arr4.map(function (item) {
        return item + 5;
    });
    console.log('res2:' + res2);

    // 需求：给数组的每一项内容拼接 666
    var res3 = arr4.map(function (item) {
        return item + '666';
    });
    console.log('res3:' + res3);

    // 需求：用li标签把所有内容都包裹起来返回 <li>1</li>
    var res4 = arr3.map(function (item) {
        return '<li>' + item + '</li>'
    }).join('');

    // var html = res4.join('');
    console.log(res4);
    document.write(res4);
    // console.log(html);

    // var list = document.getElementById('list');
    // list.innerHTML = html;

    // filter(fn): 得到执行fn后返回的true时对应的数组元素，利用这个方法课对数组元素进行过滤筛选

    // 查找数组里面小于10的数字
    var arr6 = [12, 46, 48, 2, 5, 9];
    var res5 = arr6.filter(function (item) {
        return item < 10;
    });

    console.log(res5);

    // 查找数组里面的偶数
    var res6 = arr6.filter(function (item) {
        return item % 2 == 0;
    });

    console.log(res6);

    // 查找数组里面2-15的数
    var res7 = arr6.filter(function (item) {
        return item > 2 && item < 15;
    });

    console.log(res7);

    // some(fn): 如果该函数中任何一项返回 true， 则返回true ||（或）：的写法

    // 数组里面是否含有60
    var arr7 = [1, 5, 80, 52];
    var res8 = arr7.some(function (item) {
        return item == 50;
    });

    console.log(res8);

    // every(fn): 如果该函数对每一项都返回 true， 则返回true &&（于）：的写法

    // 数组里面都是偶数
    var res9 = arr7.every(function (item) {
        return item % 2 == 0;
    });

    console.log(res9);

    // 归并
    // 求和
    var res10 = arr7.reduce(function(prev, cur) {
        return prev + cur;
    },0);

    console.log(res10);

</script>

</html>